package org.justdroid.justdroid;

import java.util.ArrayList;
import java.util.HashMap;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.PhoneLookup;

public class ContactManager {
	private Context context;
	
	ContactManager(Context context) {
		this.context = context;
	}
	
	public HashMap<String,String> getNameFromNumber(String number)
	{
		//Store name and type of number in result
		HashMap<String,String> result = new HashMap<String, String>();
		//Store the number
		result.put("number", number);
		Uri lookupUri = Uri.withAppendedPath(
		PhoneLookup.CONTENT_FILTER_URI, 
		Uri.encode(number));
		
		Cursor cursor = this.context.getContentResolver().query(lookupUri, new String[] {ContactsContract.Contacts.DISPLAY_NAME, PhoneLookup.TYPE}, null, null, null);
		try {
			if (cursor.moveToFirst()) {
				//Store the name of the contact
				result.put("name", cursor.getString(0));
				//Store the type of number
				result.put("type", context.getString(ContactsContract.CommonDataKinds.Phone.getTypeLabelResource(cursor.getInt(1))));
			}
		}
		finally {
		if (cursor != null)
			cursor.close();
		}
		return result;
	}
	
	public HashMap<String, ArrayList<String>> getNamesWithNumber(String strNumber)
	{
		//Store name and type of number in result
		HashMap<String, ArrayList<String>> result = new HashMap<String, ArrayList<String>>();
		ArrayList<String> name, number, type, id;
		name = new ArrayList<String>();
		number = new ArrayList<String>();
		type = new ArrayList<String>();
		id = new ArrayList<String>();
		Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
		        new String[]{Phone.DISPLAY_NAME, Phone.TYPE, Phone.NUMBER, Phone.CONTACT_ID},
		         Phone.NUMBER
		            + " LIKE ?", new String[] { strNumber + "%" },
		       null);
		if(cursor != null)
		while (cursor.moveToNext()) {
				name.add(cursor.getString(0));
				type.add(Phone.getTypeLabel(this.context.getResources(), cursor.getInt(1), "").toString());
				number.add(cursor.getString(2));
				id.add(cursor.getString(3));
		}
		result.put("name", name);
		result.put("number", number);
		result.put("type", type);
		result.put("id", id);
		return result;
	}
	
	public HashMap<String, ArrayList<String>> getNamesStartingWith(String strName)
	{
		//Store name and type of number in result
		HashMap<String, ArrayList<String>> result = new HashMap<String, ArrayList<String>>();
		ArrayList<String> name, id, type;
		name = new ArrayList<String>();
		id = new ArrayList<String>();
		type = new ArrayList<String>();
		String sortOrder = ContactsContract.Contacts.DISPLAY_NAME
	                + " COLLATE LOCALIZED ASC";
		Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                new String[]{ContactsContract.CommonDataKinds.Phone.CONTACT_ID, Phone.DISPLAY_NAME, Phone.TYPE}, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME +" LIKE ?", 
                new String[]{strName+"%"}, sortOrder);
		try {
			while (cursor.moveToNext()) {
				id.add(cursor.getString(0));
				name.add(cursor.getString(1));
				type.add(Phone.getTypeLabel(this.context.getResources(), cursor.getInt(2), "").toString());
			}
			result.put("name", name);
			result.put("type", type);
			result.put("id", id);
		}
		finally {
		if (cursor != null)
			cursor.close();
		}
		return result;
	}
	
	public String getNumber(String idOfContact) {
		String contactNumber = "";
		 Cursor cursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
                 new String[] {Phone.NUMBER}, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ? ", 
                 new String[]{idOfContact}, null);
		if(cursor.moveToNext()){
        	contactNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
		 }
		return contactNumber;
	}
	
	
	@SuppressLint("InlinedApi")
	public HashMap<String, ArrayList<String>> getDetailsFromNumber(String id) {
		ArrayList<String> ids, name = null, number = null, type = null, email = null;
		HashMap<String, ArrayList<String>> contacts = new HashMap<String, ArrayList<String>>();
		ids = new ArrayList<String>();
		
		Cursor cur = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, 
				ContactsContract.Contacts._ID +" = ?", new String[]{id}, "display_name" + " ASC");
		if (cur.getCount() > 0) {
		    while (cur.moveToNext()) {
		    	name = new ArrayList<String>();
				number = new ArrayList<String>();
				type = new ArrayList<String>();
				email = new ArrayList<String>();
		        String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
		       
		        
		        name.add(displayName);
		        ids.add(id);
		        Cursor pCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
		                                     null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ? ", 
		                                     new String[]{id}, null);
		        while(pCur.moveToNext()){
		            	 String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
		             	 number.add(phoneNumber);
		             	 int numberType = pCur.getInt(pCur.getColumnIndex(Phone.TYPE));
		                 String contactNumberType = Phone.getTypeLabel(this.context.getResources(), numberType, "").toString();
		                 type.add(contactNumberType);
		        }
		        pCur.close();
		        Cursor emailCur = this.context.getContentResolver().query( 
	                            ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
	                            null,
	                            ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", 
	                            new String[]{id}, null); 
	                        while (emailCur.moveToNext()) { 
	                        	String mail = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));                            
	                        	if(email.size()==0 || !email.contains(mail))// || emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.IS_PRIMARY)).equals("1"))
	                        		email.add(mail);
	            } 
	            emailCur.close();       
		    }
		}
		cur.close();
		contacts.put("name", name);
		contacts.put("numbers", number);
		contacts.put("types", type);
		contacts.put("emails", email);
		contacts.put("id", ids);
		return contacts;
	}
	
	@SuppressLint("InlinedApi")
	public HashMap<String, ArrayList<String>> getAllDetailsFromNumber(String num)
	{
		//Store name and type of number in result
		HashMap<String, ArrayList<String>> result = new HashMap<String, ArrayList<String>>();
		ArrayList<String> numbers, types;
		numbers = new ArrayList<String>();
		types = new ArrayList<String>();

		Cursor cursor = this.context.getContentResolver().query(
				Phone.CONTENT_URI, 
				null, 
				Data._ID + " = ?",
				new String[] {num}, 
				null);
		 
		try {
			if (cursor.moveToFirst()) {
				String rawContactId = cursor.getString(cursor.getColumnIndex("raw_contact_id"));
				//Store the name of the contact
				ArrayList<String> name = new ArrayList<String>();
				ArrayList<String> email = new ArrayList<String>();
			
				if(cursor.getString(cursor.getColumnIndex("display_name")) != null)
					name.add(cursor.getString(cursor.getColumnIndex("display_name")));
				    do
				    {
				        String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
				        {
				        	Cursor pCur = context.getContentResolver().query(Data.CONTENT_URI,
				        	          new String[] {Data._ID, Phone.NUMBER, Phone.TYPE, Phone.LABEL},
				        	          Data.RAW_CONTACT_ID + "=?" + " AND "
				        	                  + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'",
				        	          new String[] {String.valueOf(rawContactId)}, null);
				            while (pCur.moveToNext()) 
				            {
				                String contactNumber = pCur.getString(pCur.getColumnIndex(Phone.NUMBER));
				                int type = pCur.getInt(pCur.getColumnIndex(Phone.TYPE));
				                String contactNumberType = Phone.getTypeLabel(this.context.getResources(), type, "").toString();
				                numbers.add(contactNumber);
				                types.add(contactNumberType);
				                
				                Cursor emailCur = this.context.getContentResolver().query( 
			                            ContactsContract.CommonDataKinds.Email.CONTENT_URI, 
			                            null,
			                            ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = ?", 
			                            new String[]{id}, null); 
			                        while (emailCur.moveToNext()) { 
			                        	String mail = emailCur.getString(emailCur.getColumnIndex(ContactsContract.CommonDataKinds.Email.ADDRESS));                            

			                        	email.add(mail); //get only one mail ID for version 1 of the app 
			                        	break;
			                        } 
			                        emailCur.close();       
				            }
				            pCur.close();
				        }

				    } while (cursor.moveToNext()) ;
				
				
				result.put("name", name);
				//Store all the numbers of the contact
				result.put("numbers", numbers);
				//Store all the types of numbers of the contact
				result.put("types", types);
				//Store the email ID of the contact
				result.put("email", email);
			}
		}
		finally {
		if (cursor != null)
			cursor.close();
		}
		return result;
	}
	
	public HashMap<String,ArrayList<String>> getAllContacts() {
		ArrayList<String> ids, name, number;
		HashMap<String, ArrayList<String>> contacts = new HashMap<String, ArrayList<String>>();
		ids = new ArrayList<String>();
		name = new ArrayList<String>();
		number = new ArrayList<String>();
		
		Cursor cur = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, "display_name" + " ASC");
		if (cur.getCount() > 0) {
		    while (cur.moveToNext()) {
		        String id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
		        
		        String displayName = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
		       
		        
		        if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
		             Cursor pCur = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, 
		                                     null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ? AND " + Data.IS_PRIMARY + "=1", 
		                                     new String[]{id}, null);
		             if(pCur.moveToFirst()){
		            	 String phoneNumber = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
		             	number.add(phoneNumber);
		             	 name.add(displayName);
		             	ids.add(id);
		             }
		             pCur.close();
		        }
		    }
		}
		cur.close();
		contacts.put("name", name);
		contacts.put("number", number);
		contacts.put("id", ids);
		return contacts;
	}
	
	/** Function to get ID of a contact **/
	String getId(String contactNumber) {
		String contactId = null;
		ContentResolver contentResolver = context.getContentResolver();

		Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber));

		String[] projection = new String[] {ContactsContract.Contacts.DISPLAY_NAME, PhoneLookup._ID};

		Cursor cursor =  
		   contentResolver.query(uri, projection, null, null, null);

		if(cursor!=null) {
		  while(cursor.moveToNext()){
		    contactId = cursor.getString(cursor.getColumnIndexOrThrow(PhoneLookup._ID));
		    break;
		  }
		  cursor.close();
		}
		return contactId;
	}
	
	/** Function to get contact ID of a contact **/
	String getContactId(String contactNumber) {
		Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[] {Phone.CONTACT_ID}, Phone.NUMBER, new String[] {contactNumber}, null);
		while(cursor.moveToNext()) {
			return cursor.getString(cursor.getColumnIndex(Phone.CONTACT_ID));
		}
		return "";
	}
}
